package com.clt.ess.web;

import com.clt.ess.base.Constant;
import com.clt.ess.bean.ResultMessageBeen;
import com.clt.ess.entity.*;
import com.clt.ess.gjzw.domain.FilePackage;
import com.clt.ess.gjzw.domain.TaskNumData;
import com.clt.ess.gjzw.domain.confirmReceipt.ConfirmReceiptRequestData;
import com.clt.ess.service.*;
import com.clt.ess.utils.FastJsonUtil;
import com.clt.ess.utils.HttpUtils;
import com.clt.ess.utils.StringUtils;

import org.bouncycastle.math.raw.Mod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import java.io.*;

import java.util.ArrayList;
import java.util.List;
import static com.clt.ess.utils.Base64Utils.ESSGetBase64Encode;
import static com.clt.ess.utils.PowerUtil.getLoginUser;
import static com.clt.ess.utils.dateUtil.getDate;
import static com.clt.ess.utils.dateUtil.getTime;
import static com.clt.ess.utils.uuidUtil.getEssUUID;
import static com.clt.ess.utils.uuidUtil.getUUID;

@Controller
@RequestMapping("/make")
public class MakeController {

    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected HttpSession session;

    @Autowired
    private ISealService sealService;
    @Autowired
    private IUnitService unitService;
    @Autowired
    private ICertificateService certificateService;
    @Autowired
    private IMessageService messageService;
    @Autowired
    private ILogService logService;
    @Autowired
    private IFileTypeService fileTypeService;
    @Autowired
    private ISealImgService sealImgService;
    @Autowired
    private IGjzwService gjzwService;
    @Autowired
    private IMakeService makeService;
    @Autowired
    private IStatusPublishService statusPublishService;
    @Autowired
    private UnitImgDataService unitImgDataService;
    /**
     * 每次拦截到请求会先访问此函数
     * @param request http请求
     * @param response http回应
     */
    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response){
        this.request = request;
        this.response = response;
        this.session = request.getSession();

    }
    /**
     *访问印章制作页面
     * @param unitId 单位ID
     */
    @RequestMapping(value="/list.html", method = RequestMethod.GET)
    public String seal_make(Model model, String unitId) {

        SealApply sealApply = new SealApply();
        sealApply.setUnitId(unitId);
        //查询正在备案的申请
        sealApply.setApplyState(Constant.record_success);
        List<SealApply> sealApplyList =  sealService.findSealApply(sealApply);
        //查看制作失败的申请
        sealApply.setApplyState(Constant.MAKE_NO_COMPLETION);
        List<SealApply> sealApplyList_1 =  sealService.findSealApply(sealApply);
        sealApplyList.addAll(sealApplyList_1);
        //查看审核通过的申请
        sealApply.setApplyState(Constant.REVIEW_THROUGH);
        List<SealApply> sealApplyList_2 =  sealService.findSealApply(sealApply);
        sealApplyList.addAll(sealApplyList_2);

        model.addAttribute("unit",  unitService.findUnitById(unitId));
        model.addAttribute("sealApplyList",  sealApplyList);

        return "make/make_list";
    }
    /**
     *访问印章制作
     * @param sealApplyId 申请信息ID
     */
    @RequestMapping(value="/make_detail.html", method = RequestMethod.GET)
    public ModelAndView seal_make_detail(String sealApplyId) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error");
        //根据申请信息ID获取详细信息
        SealApply sealApply = sealService.findSealApplyById(sealApplyId);
        if(sealApply==null){
            modelAndView.setViewName("error");
        }
        modelAndView.addObject("sealApply",sealApply);
        modelAndView.setViewName("make/make_detail");
        return modelAndView;
    }
    /**
     *访问印章制作
     * @param sealApplyId
     */
    @RequestMapping(value="/make_new_do.html", method = RequestMethod.POST,produces="text/html;charset=UTF-8")
    @ResponseBody
    public String make_new_do(String sealApplyId,String ukinfo,MultipartFile gifImg,int imgWidth,int imgHeight)  {

        //保存印章图片
        String[] info = ukinfo.split("@@@@");
        String publicKey = info[0];
        String keyid = info[1];

        ResultMessageBeen messageBeen = new ResultMessageBeen();
        messageBeen.setMessage("success");
        messageBeen.setBody(null);
        //查找当前操作的申请信息
        SealApply sealApply = sealService.findSealApplyById(sealApplyId);
        sealApply.setKeyid(keyid);
        SealImg sealImg = null;
        try {
            sealImg = sealImgService.createSealImg(sealApply,gifImg,imgWidth,imgHeight);
        } catch (IOException e) {
            e.printStackTrace();
            messageBeen.setMessage("error1");
            return FastJsonUtil.toJSONString(messageBeen);
        }
        if (sealImg ==null){
            messageBeen.setMessage("error2");
            return FastJsonUtil.toJSONString(messageBeen);
        }
        //获取印章图片ID
        String sealImgId = sealImgService.addSealImg(sealImg);
        //添加ID
        sealApply.setSealImgId(sealImgId);
        sealApply.setSealImg(sealImg);

        User user =  getLoginUser(session);
        //获取唯一赋码
        String sealCodeData = gjzwService.getSealCode(Constant.applicantCert,sealApply.getUnit().getArea_number().substring(0,2));
        if (sealCodeData==null){
            System.out.println("我是统一赋码，我出错了");
            messageBeen.setMessage("error3");
            return FastJsonUtil.toJSONString(messageBeen);
        }
        //印章编码
        sealCodeData =sealApply.getUnit().getArea_number()+sealCodeData;
        sealApply.setSeal_code(sealCodeData);




        Certificate certificate = certificateService.getCertFormCA(
                 sealApply.getUnit().getCredit_code()+sealApply.getUnit().getUnitName(),
                 "1",publicKey,sealApply.getSealStartTime(),sealApply.getSealEndTime(),sealCodeData);


        if (certificate==null){
            System.out.println("我是证书，我出错了");
            messageBeen.setMessage("error4");
            return FastJsonUtil.toJSONString(messageBeen);
        }
        sealApply.setCertificateId(certificate.getCertificateId());
        sealApply.setCertificate(certificate);

        //印章备案
        TaskNumData taskNumData = sealService.recordSeal(certificate,sealApply);
        //检查备案结果
        FilePackage filePackage = sealService.checkResult(taskNumData);

        sealApply.setTaskId(taskNumData.getTaskId());

        if (filePackage==null){
            System.out.println("我是备案下载的公安加密文件，我出错了");
            messageBeen.setMessage("error5");
            return FastJsonUtil.toJSONString(messageBeen);
        }
        //状态修改为备案成功
        sealApply.setApplyState(Constant.record_success);
        //设置制作人和制作时间

        sealApply.setMakeUserId((user.getUserId()));
        sealApply.setMakeTime(getDate());
        sealApply.setEncFile(filePackage.getEncFile());
        sealApply.setDataSymKeyEnc(filePackage.getDataSymKeyEnc());
        sealApply.setAppSymKeyEnc(filePackage.getAppSymKeyEnc());

        if("success".equals(messageBeen.getMessage())){
            sealService.updateSealApply(sealApply);
            SealApply sealApply1 = sealService.findSealApplyById(sealApplyId);
            boolean result = sealService.sealApplyToSeal(sealApply1);
            if (result){
                messageBeen.setBody(sealApply.getSeal_code());
            }
        }
        return FastJsonUtil.toJSONString(messageBeen);
    }

    /**
     *延期
     * @param sealApplyId
     */
    @RequestMapping(value="/make_delay_do.html", method = RequestMethod.POST)
    @ResponseBody
    public String make_delay_do(String sealApplyId) throws IOException {
        ResultMessageBeen messageBeen = new ResultMessageBeen();
        messageBeen.setMessage("success");
        messageBeen.setBody(null);

        SealApply sealApply = sealService.findSealApplyById(sealApplyId);
        if(sealApply!=null){
            //状态修改为制作完成
            sealApply.setApplyState(Constant.MAKE_COMPLETION);
            //设置制作人和制作时间
            sealApply.setMakeUserId(((User) session.getAttribute("user")).getUserId());
            sealApply.setMakeTime(getDate());
            //更新申请信息数据

        }else{
            messageBeen.setMessage("error");
        }

        if("success".equals(messageBeen.getMessage())){
            try {
                sealService.updateSealApply(sealApply);
                //向消息中心发消息
                Message message_new_2  = new Message();
                message_new_2.setMessageNo(getEssUUID(sealApply.getUnitId()));
                message_new_2.setSender(((User) session.getAttribute("user")).getUserId());
                message_new_2.setReceiver(sealApply.getApplyUserId());
                message_new_2.setSendTime(getDate());
                message_new_2.setMessageType(Constant.Message_Type_auDelay);
                message_new_2.setMessageTitle("授权延期确认");
                message_new_2.setMessageContent("您申请"+sealApply.getSealName()+"的授权延期已审核制作完成,请您确认生效！");
                message_new_2.setApplyInfoId(sealApply.getSealApplyId());
                message_new_2.setReadState(2);
                message_new_2.setState(1);
                messageService.addMessage(message_new_2);

                User user =  getLoginUser(session);
                logService.addSystemLog("制作了"+sealApply.getSealName(),"印章制作",
                        sealApply.getUnitId(),user.getUserId(),"");

            }catch (Exception e){
                messageBeen.setMessage("error");
            }
        }
        return new String(FastJsonUtil.toJSONString(messageBeen).getBytes("utf8"),"iso8859-1");
    }

    /**
     *制作驳回
     * @param sealApplyId 申请信息ID
     */
    @RequestMapping(value="/make_reject.html", method = RequestMethod.GET)
    @ResponseBody
    public String seal_make_reject(Model model, String sealApplyId, String message) throws UnsupportedEncodingException {

        ResultMessageBeen messageBeen = new ResultMessageBeen();
        messageBeen.setMessage("success");
        messageBeen.setBody(null);

        SealApply sealApply = sealService.findSealApplyById(sealApplyId);

        if(sealApply!=null){
            //向消息中心添加数据
            Message message_new  = new Message();
            message_new.setMessageNo(Constant.JIANGSU_CODE+getUUID());
            message_new.setSender(((User) session.getAttribute("user")).getUserId());
            message_new.setReceiver(sealApply.getReviewUserId());
            message_new.setSendTime(getDate());
            message_new.setMessageType("驳回信息");
            message_new.setMessageTitle("申请"+sealApply.getSealName()+"被驳回");
            message_new.setMessageContent(message);
            message_new.setApplyInfoId(sealApply.getSealApplyId());
            message_new.setReadState(2);
            message_new.setState(1);
            boolean result = messageService.addMessage(message_new);

            //信息状态修改为审核人驳回
            sealApply.setApplyState(Constant.MAKE_NO_THROUGH);
            sealService.updateSealApply(sealApply);
            //添加日志
            User user =  (User) session.getAttribute("user");
            logService.addSystemLog("驳回了"+sealApply.getSealName()+"的制作申请","印章申请驳回",
                    sealApply.getUnitId(),user.getUserId(),"");
        }else{
            messageBeen.setMessage("error");
        }


        return new String(FastJsonUtil.toJSONString(messageBeen).getBytes("utf8"),"iso8859-1");
    }



    /**
     *更新印章证书ID
     * @param sealApplyId 申请信息ID
     */
    @RequestMapping(value="/changeCerId.html", method = RequestMethod.POST)
    @ResponseBody
    public String changeCerId(String sealApplyId,String certificateId) {
        ResultMessageBeen messageBeen = new ResultMessageBeen();
        messageBeen.setMessage("success");
        messageBeen.setBody(null);

        SealApply sealApply = sealService.findSealApplyById(sealApplyId);
        //删除印章
        Seal seal = new Seal();
        seal.setSealId(sealApply.getSealId());
        seal.setCerId(certificateId);

        sealService.updateSeal(seal);

        return FastJsonUtil.toJSONString(messageBeen);
    }

    /**
     * 查询
     * @return
     */
    @RequestMapping(value = "/writeToUK.html",produces = "text/html;charset=UTF-8")
    @ResponseBody
    private String writeToUK(String keyId)  {

        System.out.println("ess10&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
        if (keyId==null){
            return "ESSB@error@ESSE";
        }
        Seal seal = sealService.findSealByKeyId(keyId);
        if (seal==null){
            return "ESSB@error@ESSE";
        }
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("ESSB").append("@@");
        //应用维护对称密钥密文
        stringBuffer.append(seal.getAppSymKeyEnc()).append("@@");
        //数据加密对称密钥密文
        stringBuffer.append(seal.getDataSymKeyEnc()).append("@@");
        //公安下发的密钥文件
        stringBuffer.append(seal.getEncFile()).append("@@");
        //签名证书
        stringBuffer.append(seal.getCertificate().getCerBase64()).append("@@");
        //加密证书
        stringBuffer.append(seal.getCertificate().getPfxBase64()).append("@@");
        //加密密钥对称保护结构
        stringBuffer.append(seal.getCertificate().getEncKeyProtection()).append("@@");
        //图片数据
        stringBuffer.append(seal.getSealImg().getSealImgGifBase64()).append("@@");
        //公钥信息
        stringBuffer.append(seal.getCertificate().getPublicKey()).append("@@");
        //图片数据 宽
        stringBuffer.append(seal.getSealImg().getSealImageW()).append("@@");
        //图片数据 高
        stringBuffer.append(seal.getSealImg().getSealImageH()).append("@@");
        //UK中写入的文件
        stringBuffer.append(seal.getUkinfo()).append("@@");

        stringBuffer.append("ESSE");
        System.out.println("##############################################################################################");
        System.out.println("writeToUK了");
        System.out.println("##############################################################################################");
        return stringBuffer.toString();
    }


    @RequestMapping(value="/download.html",produces = "text/html;charset=UTF-8")
    @ResponseBody
    public ModelAndView download() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("make/download");
        return modelAndView;
    }
    /**
     *下载成功回执
     * @param keyId keyId
     */
    @RequestMapping(value="/make_download_success.html",produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String make_download_success(String keyId,String device_code,String EncDeviceCode) {
        EncDeviceCode = EncDeviceCode.replace("@@@@","+");
        //发送回执，入库
        Seal seal = sealService.findSealByKeyId(keyId);
        seal.setDevice_code(device_code);
        seal.setEncDeviceCode(EncDeviceCode);
        //根据sealId 找出申请信息
        SealApply sealApply = new SealApply();
        sealApply.setSealId(seal.getSealId());
        List<SealApply> sealApplyList = sealService.findSealApply(sealApply);
        if (sealApplyList!=null||sealApplyList.get(0)!=null){
            sealApply = sealApplyList.get(0);
            sealApply.setApplyState(Constant.MAKE_COMPLETION);
        }else{
            return "ESSB@error@ESSE";
        }
        
        String taskId= seal.getTaskId();
        List<ConfirmReceiptRequestData> data = new ArrayList<>();
        ConfirmReceiptRequestData confirmReceiptRequestData = new ConfirmReceiptRequestData();
        confirmReceiptRequestData.setTaskId(taskId);
        confirmReceiptRequestData.setDeviceCode(device_code);
        confirmReceiptRequestData.setYzbm(seal.getSeal_code());
        confirmReceiptRequestData.setEncDeviceCode(EncDeviceCode);
        System.out.println("##############################################################################################");
        System.out.println("make_download_success了");
        System.out.println("##############################################################################################");
        data.add(confirmReceiptRequestData);
        //访问三次
        String yzbm =gjzwService.confirmReceiptRequest(Constant.applicantCert,data);
        if (yzbm == null||"".equals(yzbm)){
            String yzbm1 = gjzwService.confirmReceiptRequest(Constant.applicantCert,data);
            if (yzbm1 == null||"".equals(yzbm)){
                String yzbm2 = gjzwService.confirmReceiptRequest(Constant.applicantCert,data);
                if (yzbm2 ==null||"".equals(yzbm)){

                    return "error";
                }else{
                    //状态发布
                    boolean result = sealService.updateSeal(seal);
                    sealService.updateSealApply(sealApply);
                    statusPublishService.sealStatusSync(yzbm2);
                    return yzbm2;
                }
            }else{
                boolean result = sealService.updateSeal(seal);
                sealService.updateSealApply(sealApply);
                statusPublishService.sealStatusSync(yzbm1);
                return yzbm1;
            }
        }else{
            boolean result = sealService.updateSeal(seal);
            sealService.updateSealApply(sealApply);
            statusPublishService.sealStatusSync(yzbm);
            return yzbm;
        }
    }


    @RequestMapping(value="/querySealByUKId.html",produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String querySealByUKId(String sUKID) {

        //发送回执，入库
        Seal seal = sealService.findSealByKeyId(sUKID);
        //调用 CalOfdHashValue 获得hash值

        StringBuffer sb = new StringBuffer();
        sb.append("ESSB@@@@");
        sb.append(seal.getUkinfo()).append("@@@@");
        sb.append("ESSE");

        return sb.toString();
    }



    @RequestMapping(value="/make1.html",produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String make1(String publicKey,String keyid,String unitId) {

        publicKey = publicKey.replace(" ","+");

        SealApply sealApply = new SealApply();
        sealApply.setSealApplyId(getUUID());
        //设置印章使用单位
        Unit unit = unitService.findUnitById(unitId);
        sealApply.setUnitId(unitId);
        sealApply.setUnit(unit);
        sealApply.setJbr_name("李津");
        sealApply.setJbr_card_type("111");
        sealApply.setJbr_card_data("123456789987654321");
        //设置制作单位
        Unit makeUnit = unitService.findUnitById("10000001");
        //设置印章类型
        sealApply.setSealTypeId("99");

        sealApply.setMake_unit_id("10000001");
        sealApply.setMakeUnit(makeUnit);
        //设置印章id
        sealApply.setSealId(getUUID());
        //设置印章名称
        sealApply.setSealName(unit.getUnitName()+"行政许可专用章");
        //设置keyId
        sealApply.setKeyid(keyid);
        //开始时间
        sealApply.setSealStartTime(getDate());
        //结束时间
        sealApply.setSealEndTime("2029-07-22 00:00:00");
        //设置申请状态
        sealApply.setApplyState(Constant.REVIEW_THROUGH);
        UnitImgData ud = unitImgDataService.findUnitImgDataByUnitId(unitId);
        //TODO 准备图片数据
        String gifImg = ud.getImgData();

        SealImg sealImg = new SealImg();
        sealImg.setSealImgId(getUUID());
        sealImg.setSealImgGifBase64(gifImg);
        sealImg.setSealImageW(40);
        sealImg.setSealImageH(40);
        sealImg.setSealImageType("png");

        //获取印章图片ID
        String sealImgId = sealImgService.addSealImg(sealImg);
        //添加ID
        sealApply.setSealImgId(sealImgId);
        sealApply.setSealImg(sealImg);


        sealService.addSealApply(sealApply);

        sealApply = sealService.findSealApplyById(sealApply.getSealApplyId());

        //获取唯一赋码
        String sealCodeData = gjzwService.getSealCode(Constant.applicantCert,sealApply.getUnit().getArea_number().substring(0,2));
        if (sealCodeData==null){
            System.out.println("我是统一赋码，我出错了");
            return "error4";
        }
        //印章编码
        sealCodeData =sealApply.getUnit().getArea_number()+sealCodeData;
        sealApply.setSeal_code(sealCodeData);

        Certificate certificate = certificateService.getCertFormCA(
                sealApply.getUnit().getCredit_code()+sealApply.getUnit().getUnitName(),
                "1",publicKey,sealApply.getSealStartTime(),sealApply.getSealEndTime(),sealCodeData);

        if (certificate==null){
            System.out.println("我是证书，我出错了");
            return "error5";
        }
        sealApply.setCertificateId(certificate.getCertificateId());
        sealApply.setCertificate(certificate);

        //印章备案
        TaskNumData taskNumData = sealService.recordSeal(certificate,sealApply);
        //检查备案结果
        FilePackage filePackage = sealService.checkResult(taskNumData);

        sealApply.setTaskId(taskNumData.getTaskId());

        if (filePackage==null){
            System.out.println("我是备案下载的公安加密文件，我出错了");
            return "error6";
        }
        //状态修改为备案成功
        sealApply.setApplyState(Constant.record_success);
        //设置制作人和制作时间

        sealApply.setMakeUserId("025user1");
        sealApply.setMakeTime(getDate());
        sealApply.setEncFile(filePackage.getEncFile());
        sealApply.setDataSymKeyEnc(filePackage.getDataSymKeyEnc());
        sealApply.setAppSymKeyEnc(filePackage.getAppSymKeyEnc());

        sealService.updateSealApply(sealApply);

        boolean result = sealService.sealApplyToSeal(sealApply);
        if (result){
            return "success";
        }else{
            return "error5";
        }
    }
}